home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / Install / program files / Borland / BDS / 3.0 / Demos / Delphi.Net / VCL / Lexer / mwD4NLexer.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2004-10-22  |  63.7 KB  |  2,291 lines

  1. {-----------------------------------------------------------------------------
  2. This Software is placed into Publlic Domain and distributed on an "AS IS" basis,
  3. WITHOUT WARRANTY OF ANY KIND, either express or implied.
  4. The Initial Developer is Martin Waldenburg
  5. (Martin.Waldenburg@T-Online.de).
  6. Contributor: James Jacobson
  7.  
  8. This lexer is processing sloppy UTF8,
  9. for copatibility to Delphi up to D7.
  10. Characters below "C0" are handled as
  11. single bytes characters.
  12.  
  13. 00-7F  Single byte character
  14. 80-BF  Trailing byte
  15. C0-DF  Leading byte of a two byte character
  16. E0-EF  Leading byte of a three byte character
  17. F0-F7  Leading byte of a four byte character
  18. F8-FB  Illegal (formerly Leading byte of a five byte character)
  19. FC-FD  Illegal (formerly Leading byte of a six byte character)
  20. FE-FF  Illegal
  21.  
  22. Byte-order marks
  23. EF BB BF         UTF-8
  24. FE FF           UTF-16/UCS-2, little endian
  25. FF FE           UTF-16/UCS-2, big endian
  26. FF FE 00 00     UTF-32/UCS-4, little endian.
  27. 00 00 FE FF     UTF-32/UCS-4, big-endian.
  28. -----------------------------------------------------------------------------}
  29. unit mwD4NLexer;
  30.  
  31. interface
  32.  
  33. uses
  34. {$IFDEF CLR}
  35.   System.Text,
  36. {$ENDIF}
  37.   SysUtils, Classes, Windows, Contnrs,
  38.   mwDelphiLanguageElements;
  39.  
  40. const
  41.   UTF8Width: array[#0..#255] of Byte = (
  42.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  43.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  44.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  45.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  46.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  47.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  48.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  49.     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6);
  50.  
  51. type
  52.   TmwLexerError = procedure(Sender: TObject; Error: string);
  53.  
  54.   TmwBinHashItem = class
  55.     HashValue: Integer;
  56.     Key: AnsiString;
  57.   end;
  58.  
  59.   TmwBinHashItemList = array of TmwBinHashItem;
  60.  
  61.   TmwBinHash = class(TObject)
  62.   protected
  63.     FList: TmwBinHashItemList;
  64.     UpperMap: array[#0..#255] of AnsiChar;
  65.     Sorted: Boolean;
  66.     fCount: Integer;
  67.     fCapacity: Integer;
  68.     procedure AddSorted(const Item: TmwBinHashItem); overload;
  69.     function CompareValue(const Value1, Value2: Integer): Integer;
  70.     function CompareString(const S1, S2: AnsiString): Boolean;
  71.     procedure Expand;
  72.     function HashOf(const Key: AnsiString): Integer; overload;
  73.     procedure InitHashTable;
  74.     procedure set_Capacity(NewCapacity: Integer);
  75.     procedure Sort;
  76.     property Capacity: Integer read fCapacity write set_Capacity;
  77.   public
  78.     constructor Create;
  79.     procedure Add(const Item: TmwBinHashItem); overload;
  80.     procedure Add(const S: AnsiString); overload;
  81.     procedure AddSorted(const S: AnsiString); overload;
  82.     procedure Clear; virtual;
  83.     procedure Delete(Index: Integer);
  84.     function get_Items(Index: Integer): TmwBinHashItem;
  85.     function IndexOf(S: AnsiString): Integer;
  86.     procedure Insert(Index: Integer; Item: TmwBinHashItem);
  87.     function Remove(S: AnsiString): Integer;
  88.     property Count: Integer read fCount;
  89.     property Items[Index: Integer]: TmwBinHashItem read get_Items; default;
  90.     property List: TmwBinHashItemList read FList;
  91.   end;
  92.  
  93.   TmwD4NLexer = class;
  94.  
  95.   TmwLexKeyListItem = class
  96.     S: AnsiString;
  97.     HashValue: Integer;
  98.     ExId: Integer;
  99.     Id: Integer;
  100.   end;
  101.  
  102. {$IFDEF CLR}
  103.   TmwLexSubKeyList = array of TmwLexKeyListItem;
  104. {$ELSE}
  105.   PmwLexSubKeyList = ^TmwLexSubKeyList;
  106.   TmwLexSubKeyList = array[0..0] of TmwLexKeyListItem;
  107. {$ENDIF}
  108.  
  109.   TmwLexKeyList = class(TObject)
  110.   private
  111.     Selector: array[0..255] of array of TmwLexKeyListItem;
  112.     function Compare(const aStart: Integer; const S: AnsiString): Boolean;
  113.   protected
  114.     Owner: TmwD4NLexer;
  115.   public
  116.     constructor Create(aOwner: TmwD4NLexer);
  117.     destructor Destroy; override;
  118.     procedure Add(const S: AnsiString; anId, anExId: Integer);
  119.     procedure Clear;
  120.     procedure Hash(const aStart: Integer);
  121.   end;
  122.  
  123.   TmwDelphiRange = (
  124.     drNormal,
  125.     drAnsiDirective,
  126.     drBorlandDirective,
  127.     drAnsiComment,
  128.     drAssemblerReference,
  129.     drBorlandComment
  130.     );
  131.  
  132.   TmwAppType = (
  133.     atGUI,
  134.     atConsole
  135.     );
  136.  
  137.   TbdBooleanDirectives = (
  138.     bdAlign,
  139.     bdAssertions,
  140.     bdBooleval,
  141.     bdDebugInfo,
  142.     bdDenyPackageUnit,
  143.     bdDesignOnly,
  144.     bdObjExportAll,
  145.     bdExtendedSyntax,
  146.     bdHints,
  147.     bdImplicitBuild,
  148.     bdImportedData,
  149.     bdIOChecks,
  150.     bdLocalSymbols,
  151.     bdLongStrings,
  152.     bdOpenStrings,
  153.     bdOptimization,
  154.     bdOverFlowChecks,
  155.     bdRangeChecks,
  156.     bdRealCompatibility,
  157.     bdRunOnly,
  158.     bdStackChecks,
  159.     bdTypeInfo,
  160.     bdDefinitionInfo,
  161.     bdSafeDivide,
  162.     bdTypedAddress,
  163.     bdVarStringChecks,
  164.     bdWarnings,
  165.     bdWeakPackageUnit,
  166.     bdStackFrames,
  167.     bdWriteableConst,
  168.     bdSymbol_Platform,
  169.     bdSymbol_Library,
  170.     bdSymbol_Deprecated,
  171.     bdUnit_Deprecated,
  172.     bdUnit_Library,
  173.     bdUnit_Platform);
  174.  
  175.   TmwBooleanDirectives = set of TbdBooleanDirectives;
  176.  
  177.   TmwLexData = class
  178.   public
  179.     ExId: Integer;
  180.     FileName: AnsiString;
  181.     Id: Integer;
  182.     LinePosition: Integer;
  183.     LineNumber: Integer;
  184. {$IFDEF CLR}
  185.     Buf: array of AnsiChar;
  186. {$ELSE}
  187.     Buf: PChar;
  188. {$ENDIF}
  189.     Range: TmwDelphiRange;
  190.     Run: Integer;
  191.     Start: Integer;
  192.     TheEnd: Integer;
  193.     RecordAlignment: Byte;
  194.     BooleanDirectives: TmwBooleanDirectives;
  195.   end;
  196.  
  197.   TmwD4NLexer = class(TObject)
  198.   private
  199.     function GetLinePosition: Integer;
  200.     function GetRun: Integer;
  201.     function GetStart: Integer;
  202.     function GetColumn: Integer;
  203.     function GetToken: AnsiString;
  204. {$IFDEF CLR}
  205.     function GetTokenWide: string;
  206. {$ELSE}
  207.     function GetTokenWide: WideString;
  208. {$ENDIF}
  209.   protected
  210.     fDescription: AnsiString;
  211.     fExtension: AnsiString;
  212.     fExternalSym: AnsiString;
  213.     fHppEmit: AnsiString;
  214.     fRecordAlignment: Byte;
  215.     fBooleanDirectives: TmwBooleanDirectives;
  216.     fApptype: TmwAppType;
  217.     fImageBase: Integer;
  218.     fResourceReserve: AnsiString;
  219.     fMaxStackSize: Integer;
  220.     fMinStackSize: Integer;
  221.     fMinEnumSize: Integer;
  222.     fNoDefine: AnsiString;
  223.     fNoInclude: AnsiString;
  224.     fResFileName: AnsiString;
  225.     fRcFileName: AnsiString;
  226.     fRegionString: AnsiString;
  227.     fDefinedList: TmwBinHash;
  228.     fDeclaredList: TmwBinHash;
  229.     fDefaultDefines: TStringList;
  230.     fEmitForHpp: Boolean;
  231.     fOnLexerError: TmwLexerError;
  232.     DirectiveStack: TStack;
  233.     KeyList: TmwLexKeyList;
  234.     DirectiveKeyList: TmwLexKeyList;
  235.     UpperMap: array[0..255] of Integer;
  236.     InIdentifiers: array[#0..#255] of Boolean;
  237.     InInternationalIdentifiers: array[#0..#255] of Boolean;
  238.     procedure CreateKeyLists;
  239.     procedure DestroyKeyLists;
  240.     procedure InitTables;
  241.     procedure InitializeKeyTables;
  242.     procedure InitializeDirectives;
  243.     function RetrieveIncludeFileName: AnsiString;
  244.     function RetrieveResourceFileName: AnsiString;
  245.     procedure SetDefaultDefines(Value: TStringList);
  246.     procedure SetDescription(Value: AnsiString);
  247.     procedure SetExtension(Value: AnsiString);
  248.     procedure SetExternalSym(Value: AnsiString);
  249.     procedure SetHppEmit(Value: AnsiString);
  250.     procedure SetImageBase(Value: Integer);
  251.     procedure SetResourceReserve(Value: AnsiString);
  252.     procedure SetMaxStackSize(Value: Integer);
  253.     procedure SetMinStackSize(Value: Integer);
  254.     procedure SetMinEnumSize(Value: Integer);
  255.     procedure SetNoDefine(Value: AnsiString);
  256.     procedure SetNoInclude(Value: AnsiString);
  257.     procedure SetResFileName(Value: AnsiString);
  258.     procedure SetRcFileName(Value: AnsiString);
  259.     procedure SetRegionString(Value: AnsiString);
  260.     procedure IdentifierHandler;
  261.     procedure InternationalIdentifierHandler;
  262.     procedure UTF8IdentifierHandler;
  263.     procedure SpaceHandler;
  264.     procedure LFHandler;
  265.     procedure CRHandler;
  266.     procedure ExclamHandler; // 33
  267.     procedure DoubleQuoteHandler; // 34
  268.     procedure SharpHandler; // 35
  269.     procedure DollarHandler; // 36
  270.     procedure PercentHandler; // 37
  271.     procedure AmpersandHandler; // 38
  272.     procedure ApostropheHandler; // 39
  273.     procedure RoundOpenHandler; // 40
  274.     procedure RoundCloseHandler; // 41
  275.     procedure AsteriskHandler; // 42
  276.     procedure PlusHandler; // 43
  277.     procedure CommaHandler; // 44
  278.     procedure MinusHandler; // 45
  279.     procedure PeriodHandler; // 46
  280.     procedure SlashHandler; // 47
  281.     procedure NumberHandler; // 48 - 57
  282.     procedure ColonHandler; // 58
  283.     procedure SemicolonHandler; // 59
  284.     procedure LessHandler; // 60
  285.     procedure EqualHandler; // 61
  286.     procedure GreaterHandler; // 62
  287.     procedure QuestionHandler; // 63
  288.     procedure AtHandler; // 64
  289.     procedure SquareOpenHandler; // 91
  290.     procedure BackslashHandler; // 92
  291.     procedure SquareCloseHandler; // 93
  292.     procedure AsciiCircumHandler; // 94
  293.     procedure QuoteLeftHandler; // 96
  294.     procedure CurlyOpenHandler; // 123
  295.     procedure BarHandler; // 124
  296.     procedure CurlyCloseHandler; // 125
  297.     procedure AsciiTildeHandler; // 126
  298.     procedure UnknownHandler;
  299.  
  300.     procedure NextAnsiComment;
  301.     procedure NextAssemblerReference;
  302.     procedure NextBorlandComment;
  303.  
  304.     procedure AnsiCommentHandler;
  305.     procedure AssemblerReferenceHandler;
  306.     procedure BorlandCommentHandler;
  307.   public
  308.     ExId: Integer;
  309.     FileName: AnsiString;
  310.     Id: Integer;
  311.     fLinePosition: Integer;
  312.     fLineNumber: Integer;
  313. {$IFDEF CLR}
  314.     Buf: array of AnsiChar;
  315. {$ELSE}
  316.     Buf: PChar;
  317. {$ENDIF}
  318.     Range: TmwDelphiRange;
  319.     Run: Integer;
  320.     Start: Integer;
  321.     TheEnd: Integer;
  322.     constructor Create;
  323.     destructor Destroy; override;
  324.     procedure AssignData(Source: TmwLexData);
  325.     procedure AssignToData(Dest: TmwLexData);
  326.     function Equals(const S: AnsiString): Boolean;
  327.     procedure Next;
  328.     procedure NextNoSpace;
  329.     procedure NextToken; virtual;
  330. {$IFDEF CLR}
  331.     procedure SetBuf(const aBuf: array of AnsiChar);
  332. {$ELSE}
  333.     procedure SetBuf(const aBuf: PChar; Len: Integer);
  334. {$ENDIF}
  335.     property Apptype: TmwAppType read fApptype write fApptype;
  336.     property BooleanDirectives: TmwBooleanDirectives read fBooleanDirectives write fBooleanDirectives;
  337.     property Column: Integer read GetColumn;
  338.     property DefaultDefines: TStringList read fDefaultDefines write SetDefaultDefines;
  339.     property DefinedList: TmwBinHash read fDefinedList;
  340.     property DeclaredList: TmwBinHash read fDeclaredList;
  341.     property Description: AnsiString read fDescription write SetDescription;
  342.     property EmitForHpp: Boolean read fEmitForHpp write fEmitForHpp;
  343.     property Extension: AnsiString read fExtension write SetExtension;
  344.     property ExternalSym: AnsiString read fExternalSym write SetExternalSym;
  345.     property HppEmit: AnsiString read fHppEmit write SetHppEmit;
  346.     property ImageBase: Integer read fImageBase write SetImageBase;
  347.     property MaxStackSize: Integer read fMaxStackSize write SetMaxStackSize;
  348.     property MinStackSize: Integer read fMinStackSize write SetMinStackSize;
  349.     property MinEnumSize: Integer read fMinEnumSize write SetMinEnumSize;
  350.     property NoDefine: AnsiString read fNoDefine write SetNoDefine;
  351.     property NoInclude: AnsiString read fNoInclude write SetNoInclude;
  352.     property LineNumber: Integer read fLineNumber;
  353.     property LinePosition: Integer read GetLinePosition;
  354.     property RecordAlignment: Byte read fRecordAlignment write fRecordAlignment;
  355.     property RegionString: AnsiString read fRegionString write SetRegionString;
  356.     property ResourceReserve: AnsiString read fResourceReserve write SetResourceReserve;
  357.     property ResFileName: AnsiString read fResFileName write SetResFileName;
  358.     property RcFileName: AnsiString read fRcFileName write SetRcFileName;
  359.     property RunPos: Integer read GetRun;
  360.     property StartPos: Integer read GetStart;
  361.     property Token: AnsiString read GetToken;
  362. {$IFDEF CLR}
  363.     property WideToken: string read GetTokenWide;
  364. {$ELSE}
  365.     property WideToken: WideString read GetTokenWide;
  366. {$ENDIF}
  367.     property OnLexerError: TmwLexerError read fOnLexerError write fOnLexerError;
  368.   end;
  369.  
  370. implementation
  371.  
  372. { TmwBinHash }
  373.  
  374. procedure TmwBinHash.Add(const S: AnsiString);
  375. var
  376.   Item: TmwBinHashItem;
  377. begin
  378.   Item := TmwBinHashItem.Create;
  379.   Item.Key := S;
  380.   Add(Item);
  381. end;
  382.  
  383. procedure TmwBinHash.Add(const Item: TmwBinHashItem);
  384. begin
  385.   if Item <> nil then
  386.   begin
  387.     Item.HashValue := HashOf(Item.Key);
  388.     if fCount < 7000 then
  389.     begin
  390.       AddSorted(Item);
  391.     end else
  392.     begin
  393.       Sorted := False;
  394.       Insert(fCount, Item);
  395.     end;
  396.   end;
  397. end;
  398.  
  399. procedure TmwBinHash.AddSorted(const S: AnsiString);
  400. var
  401.   Item: TmwBinHashItem;
  402. begin
  403.   Item := TmwBinHashItem.Create;
  404.   Item.Key := S;
  405.   Item.HashValue := HashOf(Item.Key);
  406.   AddSorted(Item);
  407. end;
  408.  
  409. procedure TmwBinHash.AddSorted(const Item: TmwBinHashItem);
  410. var
  411.   Value, First, Last, Temp: Integer;
  412.   Larger: ByteBool;
  413. begin
  414.   Value := Item.HashValue;
  415.   Larger := False;
  416.   Temp := 0;
  417.   if fCount > 0 then
  418.   begin
  419.     if not sorted then Sort;
  420.     First := 0;
  421.     Last := fCount - 1;
  422.     while First <= Last do
  423.     begin
  424.       Temp := (First + Last) shr 1;
  425.       case CompareValue(Value, TmwBinHashItem(fList[Temp]).HashValue) of
  426.         -1:
  427.           begin
  428.             Last := Temp - 1;
  429.             Larger := False;
  430.           end;
  431.         0:
  432.           begin
  433.             Larger := False;
  434.             break;
  435.           end;
  436.         1:
  437.           begin
  438.             First := Temp + 1;
  439.             Larger := True;
  440.           end;
  441.       end;
  442.     end;
  443.     case Larger of
  444.       True: Insert(Temp + 1, Item);
  445.       False: Insert(Temp, Item);
  446.     end;
  447.   end else Insert(0, Item);
  448. end;
  449.  
  450. procedure TmwBinHash.Clear;
  451. var
  452.   I: Integer;
  453. begin
  454.   for I := 0 to fCount - 1 do
  455.     fList[I].Free;
  456.   SetLength(fList, 0);
  457.   fCount := 0;
  458.   fCapacity := 0;
  459.   Sorted := True;
  460. end;
  461.  
  462. function TmwBinHash.CompareString(const S1, S2: AnsiString): Boolean;
  463. var
  464.   I: Integer;
  465. begin
  466.   Result := False;
  467.   if Length(S1) <> Length(S2) then Exit;
  468.   begin
  469.     Result := True;
  470.     for I := Length(S1) downto 1 do
  471.       if S1[I] <> S2[I] then
  472.         if UpperMap[S1[I]] <> UpperMap[S2[I]] then
  473.         begin
  474.           Result := False;
  475.           Exit;
  476.         end;
  477.   end;
  478. end;
  479.  
  480. function TmwBinHash.CompareValue(const Value1, Value2: Integer): Integer;
  481. begin
  482.   Result := 0;
  483.   if Value1 < Value2 then Result := -1 else
  484.     if Value1 > Value2 then Result := 1;
  485. end;
  486.  
  487. constructor TmwBinHash.Create;
  488. begin
  489.   inherited Create;
  490.   InitHashTable;
  491. end;
  492.  
  493. procedure TmwBinHash.Delete(Index: Integer);
  494. begin
  495.   if (Index >= 0) and (Index < fCount) then
  496.   begin
  497. {$IFDEF CLR}
  498.     dec(fCount);
  499.     System.array.Copy(FList, Index + 1, FList, Index,
  500.       fCount - Index);
  501. {$ELSE}
  502.     FList[Index].Free;
  503.     dec(fCount);
  504.     if Index < fCount then
  505.       System.Move(FList[Index + 1], FList[Index],
  506.         (fCount - Index) * SizeOf(TmwBinHashItem));
  507. {$ENDIF}
  508.   end;
  509. end;
  510.  
  511. procedure TmwBinHash.Expand;
  512. begin
  513.   set_Capacity(fCount + 2 + fCount div 10);
  514. end;
  515.  
  516. function TmwBinHash.get_Items(Index: Integer): TmwBinHashItem;
  517. begin
  518.   Result := TmwBinHashItem(FList[Index]);
  519. end;
  520.  
  521. function TmwBinHash.HashOf(const Key: AnsiString): Integer;
  522. {modified version of HashDKC3 posted to  delphi.language.basm}
  523. var
  524. {$IFDEF CLR}
  525.   I: Integer;
  526. {$ELSE}
  527.   P, P2: PChar;
  528. {$ENDIF}
  529. begin
  530.   Result := 0;
  531. {$IFDEF CLR}
  532.   for I := 1 to Length(Key) do
  533.     Result := Result shl 10 - Result shl 5 - Result + Ord(Key[I]);
  534. {$ELSE}
  535.   P := PChar(Key);
  536.   P2 := P + Length(Key);
  537.   while P < P2 do
  538.   begin
  539.     Result := Result shl 10 - Result shl 5 - Result + Ord(P^);
  540.     inc(P);
  541.   end;
  542. {$ENDIF}
  543. end;
  544.  
  545. function TmwBinHash.IndexOf(S: AnsiString): Integer;
  546. var
  547.   Value, First, Last, Temp: Integer;
  548. begin
  549.   if not sorted then Sort;
  550.   Value := HashOf(s);
  551.   Result := -1;
  552.   First := 0;
  553.   Last := fCount - 1;
  554.   Temp := -1;
  555.   while First <= Last do
  556.   begin
  557.     Temp := (First + Last) shr 1;
  558.     if Value < TmwBinHashItem(fList[Temp]).HashValue then
  559.       Last := Temp - 1
  560.     else
  561.       if Value > TmwBinHashItem(fList[Temp]).HashValue then
  562.         First := Temp + 1
  563.       else Break;
  564.   end;
  565.   if Temp = -1 then Exit;
  566.   repeat
  567.     dec(Temp);
  568.   until (Temp < 0) or (Value <> TmwBinHashItem(fList[Temp]).HashValue);
  569.   inc(Temp);
  570.   while (Temp < fCount) and (Value = TmwBinHashItem(fList[Temp]).HashValue) do
  571.     case CompareString(S, TmwBinHashItem(fList[Temp]).Key) of
  572.       True:
  573.         begin
  574.           Result := Temp;
  575.           Exit;
  576.         end;
  577.       False: inc(Temp);
  578.     end;
  579. end;
  580.  
  581. procedure TmwBinHash.InitHashTable;
  582. var
  583.   I: AnsiChar;
  584.   C: array[0..1] of AnsiChar;
  585.   S: AnsiString;
  586. begin
  587.   C[1] := #0;
  588.   for I := #0 to #255 do
  589.   begin
  590.     C[0] := I;
  591.     S := AnsiUpperCase(C);
  592.     case S <> '' of
  593.       True: UpperMap[I] := S[1];
  594.       False: UpperMap[I] := I;
  595.     end;
  596.   end;
  597. end;
  598.  
  599. procedure TmwBinHash.Insert(Index: Integer; Item: TmwBinHashItem);
  600. begin
  601.   if fCount = Capacity then
  602.     Expand;
  603. {$IFDEF CLR}
  604.   if Index < fCount then
  605.     System.array.Copy(FList, Index, FList, Index + 1,
  606.       fCount - Index);
  607. {$ELSE}
  608.   if Index < fCount then
  609.     System.Move(FList[Index], FList[Index + 1],
  610.       (fCount - Index) * SizeOf(TmwBinHashItem));
  611. {$ENDIF}
  612.   FList[Index] := Item;
  613.   inc(fCount);
  614. end;
  615.  
  616. function TmwBinHash.Remove(S: AnsiString): Integer;
  617. begin
  618.   Result := IndexOf(S);
  619.   if Result >= 0 then
  620.     Delete(Result);
  621. end;
  622.  
  623. procedure TmwBinHash.set_Capacity(NewCapacity: Integer);
  624. var
  625.   I: Integer;
  626. begin
  627.   if NewCapacity <> Capacity then
  628.   begin
  629.     if NewCapacity < fCount then
  630.       for I := NewCapacity to fCount - 1 do
  631.         fList[I].Free;
  632.     SetLength(fList, NewCapacity);
  633.     FCapacity := NewCapacity;
  634.   end;
  635. end;
  636.  
  637. { Based on a non-recursive QuickSort from the SWAG-Archive.
  638.   ( TV Sorting Unit by Brad Williams ) }
  639.  
  640. procedure TmwBinHash.Sort;
  641. var
  642.   Left, Right, SubArray, SubLeft, SubRight: LongInt;
  643.   Temp, Pivot: TmwBinHashItem;
  644.   Stack: array[1..32] of record First, Last: LongInt;
  645.   end;
  646. begin
  647.   if fCount < 2 then Exit;
  648.   SubArray := 1;
  649.   Stack[SubArray].First := 0;
  650.   Stack[SubArray].Last := fCount - 1;
  651.   repeat
  652.     Left := Stack[SubArray].First;
  653.     Right := Stack[SubArray].Last;
  654.     Dec(SubArray);
  655.     repeat
  656.       SubLeft := Left;
  657.       SubRight := Right;
  658.       Pivot := TmwBinHashItem(fList[(Left + Right) shr 1]);
  659.       repeat
  660.         while CompareValue(TmwBinHashItem(fList[SubLeft]).HashValue, Pivot.HashValue) < 0 do Inc(SubLeft);
  661.         while CompareValue(TmwBinHashItem(fList[SubRight]).HashValue, Pivot.HashValue) > 0 do Dec(SubRight);
  662.         if SubLeft <= SubRight then
  663.         begin
  664.           Temp := TmwBinHashItem(fList[SubLeft]);
  665.           fList[SubLeft] := fList[SubRight];
  666.           fList[SubRight] := Temp;
  667.           Inc(SubLeft);
  668.           Dec(SubRight);
  669.         end;
  670.       until SubLeft > SubRight;
  671.       if SubLeft < Right then
  672.       begin
  673.         Inc(SubArray);
  674.         Stack[SubArray].First := SubLeft;
  675.         Stack[SubArray].Last := Right;
  676.       end;
  677.       Right := SubRight;
  678.     until Left >= Right;
  679.   until SubArray = 0;
  680.   Sorted := True;
  681. end;
  682.  
  683. { TmwLexKeyList }
  684.  
  685. procedure TmwLexKeyList.Add(const S: AnsiString; anId, anExId: Integer);
  686. var
  687.   Key: Integer;
  688.   Item: TmwLexKeyListItem;
  689. {$IFDEF CLR}
  690.   Sub: TmwLexSubKeyList;
  691. {$ELSE}
  692.   Sub: PmwLexSubKeyList;
  693. {$ENDIF}
  694.   Value2, Count, First, Last, Temp: Integer;
  695.   Larger: Boolean;
  696. begin
  697.   case S = '' of
  698.     True: Exit;
  699.     False:
  700.       begin
  701.         Item := TmwLexKeyListItem.Create;
  702.         Item.S := S;
  703.         Item.HashValue := Owner.UpperMap[Ord(S[Length(S)])] shl Length(S);
  704.         Item.Id := anId;
  705.         Item.ExId := anExId;
  706.         Key := Owner.UpperMap[Ord(S[1])];
  707.         Count := Length(Selector[Key]);
  708. {$IFDEF CLR}
  709.         Sub := Selector[Key];
  710. {$ELSE}
  711.         Sub := Pointer(Selector[Key]);
  712. {$ENDIF}
  713.         Larger := False;
  714.         Temp := 0;
  715.         if Count > 0 then
  716.         begin
  717.           First := 0;
  718.           Last := Count - 1;
  719.           while First <= Last do
  720.           begin
  721.             Temp := (First + Last) shr 1;
  722.             Value2 := Sub[Temp].HashValue;
  723.             if Item.HashValue < Value2 then
  724.             begin
  725.               Last := Temp - 1;
  726.               Larger := False;
  727.             end
  728.             else
  729.               if Item.HashValue > Value2 then
  730.               begin
  731.                 First := Temp + 1;
  732.                 Larger := True;
  733.               end
  734.               else
  735.               begin
  736.                 Larger := False;
  737.                 break;
  738.               end;
  739.           end;
  740.           case Larger of
  741.             True: inc(Temp);
  742.           end;
  743.         end;
  744.         inc(Count);
  745.         SetLength(Selector[Key], Count);
  746.         if Temp < Count then
  747. {$IFDEF CLR}
  748.           System.array.Copy(Selector[Key], Temp, Selector[Key], Temp + 1, Count - Temp - 1);
  749. {$ELSE}
  750.           System.Move(Selector[Key][Temp], Selector[Key][Temp + 1], (Count - Temp - 1) * SizeOf(Pointer));
  751. {$ENDIF}
  752.         Selector[Key][Temp] := Item;
  753.       end;
  754.   end;
  755. end;
  756.  
  757. procedure TmwLexKeyList.Clear;
  758. var
  759.   I, J: Integer;
  760. begin
  761.   for I := 0 to 255 do
  762.     if Selector[I] <> nil then
  763.     begin
  764.       for J := 0 to Length(Selector[I]) - 1 do
  765.       begin
  766.         Selector[I][J].S := '';
  767.         Selector[I][J].Free;
  768.       end;
  769.       SetLength(Selector[I], 0);
  770.     end;
  771. end;
  772.  
  773. function TmwLexKeyList.Compare(const aStart: Integer; const S: AnsiString): Boolean;
  774. var
  775.   I, J: Integer;
  776. begin
  777.   Result := False;
  778.   J := Length(S);
  779.   if Owner.Run - aStart = J then
  780.   begin
  781.     Result := True;
  782.     dec(J);
  783.     for I := Owner.Run - 2 downto aStart + 1 do
  784.       if Owner.UpperMap[Ord(Owner.Buf[I])] <> Owner.UpperMap[Ord(S[J])] then
  785.       begin
  786.         Result := False;
  787.         Exit;
  788.       end else dec(J);
  789.   end;
  790. end;
  791.  
  792. constructor TmwLexKeyList.Create(aOwner: TmwD4NLexer);
  793. begin
  794.   inherited Create;
  795.   Owner := aOwner;
  796. end;
  797.  
  798. destructor TmwLexKeyList.Destroy;
  799. begin
  800.   Clear;
  801.   inherited Destroy;
  802. end;
  803.  
  804. procedure TmwLexKeyList.Hash(const aStart: Integer);
  805. var
  806.   Key: Byte;
  807.   Count, Value, Value2: Integer;
  808. {$IFDEF CLR}
  809.   Sub: TmwLexSubKeyList;
  810. {$ELSE}
  811.   Sub: PmwLexSubKeyList;
  812. {$ENDIF}
  813.   Item: TmwLexKeyListItem;
  814.   First, Last, Temp: Integer;
  815. begin
  816.   Key := Owner.UpperMap[Ord(Owner.Buf[aStart])];
  817.   Count := Length(Selector[Key]);
  818. {$IFDEF CLR}
  819.   Sub := Selector[Key];
  820. {$ELSE}
  821.   Sub := Pointer(Selector[Key]);
  822. {$ENDIF}
  823.   begin
  824.     First := 0;
  825.     Last := Count - 1;
  826.     Temp := -1;
  827.     Value := Owner.UpperMap[Ord(Owner.Buf[Owner.Run - 1])] shl (Owner.Run - aStart);
  828.     while First <= Last do
  829.     begin
  830.       Temp := (First + Last) div 2;
  831.       Value2 := Sub[Temp].HashValue;
  832.       if Value < Value2 then
  833.         Last := Temp - 1
  834.       else
  835.         if Value > Value2 then
  836.           First := Temp + 1
  837.         else Break;
  838.     end;
  839.     if (Temp > -1) and (Value = Sub[Temp].HashValue) then
  840.     begin
  841.       dec(Temp);
  842.       while (Temp > -1) and (Value = Sub[Temp].HashValue) do
  843.         dec(Temp);
  844.       inc(Temp);
  845.       while (Temp < Count) and (Value = Sub[Temp].HashValue) do
  846.         case Compare(aStart, Sub[Temp].S) of
  847.           True:
  848.             begin
  849.               Item := Sub[Temp];
  850.               Owner.Id := Item.Id;
  851.               Owner.ExId := Item.ExId;
  852.               Exit;
  853.             end;
  854.           False: inc(Temp);
  855.         end;
  856.     end;
  857.   end;
  858. end;
  859.  
  860. { TmwD4NLexer }
  861.  
  862. procedure TmwD4NLexer.AnsiCommentHandler;
  863. begin
  864.   Id := leAnsiComment;
  865.   while Run < TheEnd do
  866.   begin
  867.     case Buf[Run] of
  868.       #10: Exit;
  869.  
  870.       #13:
  871.         case (Run + 1 < TheEnd) and (Buf[Run + 1] = #10) of
  872.           True: Exit;
  873.           False: inc(Run);
  874.         end;
  875.  
  876.       '*':
  877.         case (Run + 1 < TheEnd) and (Buf[Run + 1] = ')') of
  878.           True:
  879.             begin
  880.               inc(Run, 2);
  881.               Range := drNormal;
  882.               Exit;
  883.             end;
  884.           False: inc(Run);
  885.         end;
  886.     else
  887.       case Run + UTF8Width[Buf[Run]] < TheEnd of
  888.         True: inc(Run, UTF8Width[Buf[Run]]);
  889.         False: inc(Run);
  890.       end;
  891.     end;
  892.   end;
  893. end;
  894.  
  895. procedure TmwD4NLexer.AmpersandHandler;
  896. begin
  897.   inc(Run);
  898.   Id := leAmpersand;
  899. end;
  900.  
  901. procedure TmwD4NLexer.ApostropheHandler;
  902. begin
  903.   inc(Run);
  904.   Id := leUnterminatedStringConstant;
  905.   while Run < TheEnd do
  906.     case Buf[Run] of
  907.       #10, #13: Break;
  908.       #39:
  909.         begin
  910.           inc(Run);
  911.           case Run < TheEnd of
  912.             True:
  913.               case Buf[Run] = #39 of
  914.                 True: inc(Run);
  915.                 False:
  916.                   begin
  917.                     Id := leStringConstant;
  918.                     Break;
  919.                   end;
  920.               end;
  921.             False:
  922.               begin
  923.                 Id := leStringConstant;
  924.                 Break;
  925.               end;
  926.           end;
  927.         end;
  928.     else
  929.       case Run + UTF8Width[Buf[Run]] < TheEnd of
  930.         True: inc(Run, UTF8Width[Buf[Run]]);
  931.         False: inc(Run);
  932.       end;
  933.  
  934.     end;
  935. end;
  936.  
  937. procedure TmwD4NLexer.AsciiCircumHandler;
  938. begin
  939.   inc(Run);
  940.   Id := leAsciiCircum;
  941. end;
  942.  
  943. procedure TmwD4NLexer.AsciiTildeHandler;
  944. begin
  945.   inc(Run);
  946.   Id := leAsciiTilde;
  947. end;
  948.  
  949. procedure TmwD4NLexer.AssemblerReferenceHandler;
  950. begin
  951.   Id := leAssemblerReference;
  952.   while Run < TheEnd do
  953.   begin
  954.     case Buf[Run] of
  955.       #10: Exit;
  956.  
  957.       #13:
  958.         case (Run + 1 < TheEnd) and (Buf[Run + 1] = #10) of
  959.           True: Exit;
  960.           False: inc(Run);
  961.         end;
  962.  
  963.       '}':
  964.         begin
  965.           inc(Run);
  966.           Range := drNormal;
  967.           Exit;
  968.         end;
  969.     else
  970.       case Run + UTF8Width[Buf[Run]] < TheEnd of
  971.         True: inc(Run, UTF8Width[Buf[Run]]);
  972.         False: inc(Run);
  973.       end;
  974.     end;
  975.   end;
  976. end;
  977.  
  978. procedure TmwD4NLexer.AssignData(Source: TmwLexData);
  979. begin
  980.   if (Source <> nil) then
  981.   begin
  982.     ExId := Source.ExId;
  983.     FileName := Source.FileName;
  984.     Id := Source.Id;
  985.     fLinePosition := Source.LinePosition;
  986.     fLineNumber := Source.LineNumber;
  987.     Buf := Source.Buf;
  988.     Range := Source.Range;
  989.     Run := Source.Run;
  990.     Start := Source.Start;
  991.     TheEnd := Source.TheEnd;
  992.     RecordAlignment := Source.RecordAlignment;
  993.     BooleanDirectives := Source.BooleanDirectives;
  994.   end;
  995. end;
  996.  
  997. procedure TmwD4NLexer.AssignToData(Dest: TmwLexData);
  998. begin
  999.   if (Dest <> nil) then
  1000.   begin
  1001.     Dest.ExId := ExId;
  1002.     Dest.FileName := FileName;
  1003.     Dest.Id := Id;
  1004.     Dest.LinePosition := LinePosition;
  1005.     Dest.LineNumber := LineNumber;
  1006.     Dest.Buf := Buf;
  1007.     Dest.Range := Range;
  1008.     Dest.Run := Run;
  1009.     Dest.Start := Start;
  1010.     Dest.TheEnd := TheEnd;
  1011.     Dest.RecordAlignment := fRecordAlignment;
  1012.     Dest.BooleanDirectives := fBooleanDirectives;
  1013.   end;
  1014. end;
  1015.  
  1016. procedure TmwD4NLexer.AsteriskHandler;
  1017. begin
  1018.   inc(Run);
  1019.   Id := leAsterisk;
  1020.   if Range in [drAnsiComment, drAnsiDirective] then
  1021.     if Run < TheEnd then
  1022.       if Buf[Run] = ')' then
  1023.       begin
  1024.         inc(Run);
  1025.         Id := leEndOfAnsiComment;
  1026.         Range := drNormal;
  1027.       end;
  1028. end;
  1029.  
  1030. procedure TmwD4NLexer.AtHandler;
  1031. begin
  1032.   inc(Run);
  1033.   Id := leAt;
  1034.   if (Run < TheEnd) and (Buf[Run] = '@') then
  1035.   begin
  1036.     Id := leDoubleAt;
  1037.     inc(Run);
  1038.   end;
  1039. end;
  1040.  
  1041. procedure TmwD4NLexer.BackslashHandler;
  1042. begin
  1043.   inc(Run);
  1044.   Id := leBackSlash;
  1045. end;
  1046.  
  1047. procedure TmwD4NLexer.BarHandler;
  1048. begin
  1049.   inc(Run);
  1050.   Id := leBar;
  1051. end;
  1052.  
  1053. procedure TmwD4NLexer.BorlandCommentHandler;
  1054. begin
  1055.   Id := leBorlandComment;
  1056.   while Run < TheEnd do
  1057.   begin
  1058.     case Buf[Run] of
  1059.       #10: Exit;
  1060.  
  1061.       #13:
  1062.         case (Run + 1 < TheEnd) and (Buf[Run + 1] = #10) of
  1063.           True: Exit;
  1064.           False: inc(Run);
  1065.         end;
  1066.  
  1067.       '}':
  1068.         begin
  1069.           inc(Run);
  1070.           Range := drNormal;
  1071.           Exit;
  1072.         end;
  1073.     else
  1074.       case Run + UTF8Width[Buf[Run]] < TheEnd of
  1075.         True: inc(Run, UTF8Width[Buf[Run]]);
  1076.         False: inc(Run);
  1077.       end;
  1078.     end;
  1079.   end;
  1080. end;
  1081.  
  1082. procedure TmwD4NLexer.ColonHandler;
  1083. begin
  1084.   inc(Run);
  1085.   Id := leColon;
  1086.   if (Run < TheEnd) and (Buf[Run] = '=') then
  1087.   begin
  1088.     Id := leAssignment;
  1089.     inc(Run);
  1090.   end;
  1091. end;
  1092.  
  1093. procedure TmwD4NLexer.CommaHandler;
  1094. begin
  1095.   inc(Run);
  1096.   Id := leComma;
  1097. end;
  1098.  
  1099. constructor TmwD4NLexer.Create;
  1100. begin
  1101.   inherited Create;
  1102.   DirectiveStack := TStack.Create;
  1103.   fDefaultDefines := TstringList.Create;
  1104.   fDefinedList := TmwBinHash.Create;
  1105.   fDeclaredList := TmwBinHash.Create;
  1106.   InitializeDirectives;
  1107.   InitTables;
  1108.   CreateKeyLists;
  1109.   InitializeKeyTables;
  1110. end;
  1111.  
  1112. procedure TmwD4NLexer.CreateKeyLists;
  1113. begin
  1114.   KeyList := TmwLexKeyList.Create(Self);
  1115.   DirectiveKeyList := TmwLexKeyList.Create(Self);
  1116. end;
  1117.  
  1118. procedure TmwD4NLexer.CRHandler;
  1119. begin
  1120.   inc(Run);
  1121.   Id := leSpace;
  1122.   if (Run < TheEnd) and (Buf[Run] = #10) then
  1123.   begin
  1124.     Id := leLineEnd;
  1125.     inc(Run);
  1126.     fLinePosition := Start;
  1127.     inc(fLineNumber);
  1128.   end;
  1129. end;
  1130.  
  1131. procedure TmwD4NLexer.CurlyCloseHandler;
  1132. begin
  1133.   inc(Run);
  1134.   Id := leCurlyClose;
  1135.   if Range in [drBorlandComment, drBorlandDirective] then
  1136.     Range := drNormal;
  1137. end;
  1138.  
  1139. procedure TmwD4NLexer.CurlyOpenHandler;
  1140. begin
  1141.   inc(Run);
  1142.   Id := leCurlyOpen;
  1143.   if Range = drNormal then
  1144.     case Run < TheEnd of
  1145.       True:
  1146.         case Buf[Run] of
  1147.           '$':
  1148.             begin
  1149.               inc(Run);
  1150.               Id := leBeginOfBorlandDirective;
  1151.               Range := drBorlandDirective;
  1152.             end;
  1153.           '%':
  1154.             begin
  1155.               inc(Run);
  1156.               Id := leAssemblerReference;
  1157.               Range := drAssemblerReference;
  1158.               AssemblerReferenceHandler;
  1159.             end;
  1160.         else
  1161.           begin
  1162.             Range := drBorlandComment;
  1163.             BorlandCommentHandler;
  1164.           end;
  1165.         end;
  1166.       False:
  1167.         begin
  1168.           Range := drBorlandComment;
  1169.           BorlandCommentHandler;
  1170.         end;
  1171.     end;
  1172. end;
  1173.  
  1174. destructor TmwD4NLexer.Destroy;
  1175. begin
  1176.   DirectiveStack.Free;
  1177.   fDefaultDefines.Free;
  1178.   fDefinedList.Free;
  1179.   fDeclaredList.Free;
  1180.   DestroyKeyLists;
  1181.   inherited Destroy;
  1182. end;
  1183.  
  1184. procedure TmwD4NLexer.DestroyKeyLists;
  1185. begin
  1186.   KeyList.Free;
  1187.   DirectiveKeyList.Free;
  1188. end;
  1189.  
  1190. procedure TmwD4NLexer.DollarHandler;
  1191. begin
  1192.   inc(Run);
  1193.   Id := leDollar;
  1194.   if (Run < TheEnd) and
  1195.     ((Buf[Run] >= '0') and (Buf[Run] <= '9')) or
  1196.     ((Buf[Run] >= 'a') and (Buf[Run] <= 'f')) or
  1197.     ((Buf[Run] >= 'A') and (Buf[Run] <= 'F')) then
  1198.   begin
  1199.     inc(Run);
  1200.     Id := leHexNumber;
  1201.     while (Run < TheEnd) and
  1202.       ((Buf[Run] >= '0') and (Buf[Run] <= '9')) or
  1203.       ((Buf[Run] >= 'a') and (Buf[Run] <= 'f')) or
  1204.       ((Buf[Run] >= 'A') and (Buf[Run] <= 'F')) do
  1205.       inc(Run);
  1206.   end;
  1207. end;
  1208.  
  1209. procedure TmwD4NLexer.DoubleQuoteHandler;
  1210. begin
  1211.   inc(Run);
  1212.   Id := leDoubleQuote;
  1213. end;
  1214.  
  1215. procedure TmwD4NLexer.EqualHandler;
  1216. begin
  1217.   inc(Run);
  1218.   Id := leEqual;
  1219. end;
  1220.  
  1221. function TmwD4NLexer.Equals(const S: AnsiString): Boolean;
  1222. var
  1223.   I: Integer;
  1224.   J: Integer;
  1225. begin
  1226.   Result := False;
  1227.   J := Length(S);
  1228.   if Run - Start = J then
  1229.     case ExId of
  1230.       leUTF8Identifier:
  1231.         begin
  1232.           Result := True;
  1233.           for I := Run - 1 downto Start do
  1234.           begin
  1235.             if Buf[I] <> S[J] then
  1236.             begin
  1237.               Result := False;
  1238.               break;
  1239.             end;
  1240.             dec(J);
  1241.           end;
  1242.           if Result = False then
  1243.           begin
  1244. {$IFDEF CLR}
  1245.             Result :=
  1246.               UpperCase(System.Text.Encoding.UTF8.GetString(TBytes(S)))
  1247.               =
  1248.               UpperCase(System.Text.Encoding.UTF8.GetString(TBytes(Buf), Start, Run - Start));
  1249. {$ELSE}
  1250.             Result :=
  1251.               UpperCase(UTF8Decode(S))
  1252.               =
  1253.               UpperCase(UTF8Decode(Copy(Buf, Start, Run - Start)));
  1254. {$ENDIF}
  1255.           end;
  1256.         end;
  1257.       leIdentifier:
  1258.         begin
  1259.           Result := True;
  1260.           for I := Run - 1 downto Start do
  1261.           begin
  1262.             if Buf[I] <> S[J] then
  1263.               if UpperMap[Ord(Buf[I])] <> UpperMap[Ord(S[J])] then
  1264.               begin
  1265.                 Result := False;
  1266.                 Exit;
  1267.               end;
  1268.             dec(J);
  1269.           end;
  1270.         end;
  1271.     else
  1272.       begin
  1273.         Result := True;
  1274.         for I := Run - 1 downto Start do
  1275.         begin
  1276.           if Buf[I] <> S[J] then
  1277.           begin
  1278.             Result := False;
  1279.             Exit;
  1280.           end;
  1281.           dec(J);
  1282.         end;
  1283.       end;
  1284.     end;
  1285. end;
  1286.  
  1287. procedure TmwD4NLexer.ExclamHandler;
  1288. begin
  1289.   inc(Run);
  1290.   Id := leExclam;
  1291. end;
  1292.  
  1293. function TmwD4NLexer.GetColumn: Integer;
  1294. begin
  1295.   Result := Start - LinePosition;
  1296. end;
  1297.  
  1298. function TmwD4NLexer.GetLinePosition: Integer;
  1299. begin
  1300.   Result := LinePosition;
  1301. end;
  1302.  
  1303. function TmwD4NLexer.GetRun: Integer;
  1304. begin
  1305.   Result := Run;
  1306. end;
  1307.  
  1308. function TmwD4NLexer.GetStart: Integer;
  1309. begin
  1310.   Result := Start;
  1311. end;
  1312.  
  1313. function TmwD4NLexer.GetToken: AnsiString;
  1314. begin
  1315.   SetLength(Result, Run - Start);
  1316. {$IFDEF CLR}
  1317.   System.array.Copy(Buf, Start, Result, 0, Run - Start);
  1318. {$ELSE}
  1319.   System.Move(Buf[Start], Result[1], Run - Start);
  1320. {$ENDIF}
  1321. end;
  1322.  
  1323. {$IFDEF CLR}
  1324.  
  1325. function TmwD4NLexer.GetTokenWide: string;
  1326. {$ELSE}
  1327.  
  1328. function TmwD4NLexer.GetTokenWide: WideString;
  1329. {$ENDIF}
  1330. begin
  1331. {$IFDEF CLR}
  1332.   Result := System.Text.Encoding.UTF8.GetString(TBytes(Buf), Start, Run - Start);
  1333. {$ELSE}
  1334.   Result := UTF8Decode(Copy(Buf, Start, Run - Start));
  1335. {$ENDIF}
  1336. end;
  1337.  
  1338. procedure TmwD4NLexer.GreaterHandler;
  1339. begin
  1340.   inc(Run);
  1341.   Id := leGreater;
  1342.   if (Run < TheEnd) and (Buf[Run] = '=') then
  1343.   begin
  1344.     Id := leGreaterOrEqual;
  1345.     inc(Run);
  1346.   end;
  1347. end;
  1348.  
  1349. procedure TmwD4NLexer.IdentifierHandler;
  1350. begin
  1351.   inc(Run);
  1352.   Id := leIdentifier;
  1353.   ExId := leIdentifier;
  1354.   while (Run < TheEnd) do
  1355.     case InIdentifiers[Buf[Run]] of
  1356.       True: inc(Run);
  1357.       False: Break;
  1358.     end;
  1359.   case InInternationalIdentifiers[Buf[Run]] of
  1360.     True: InternationalIdentifierHandler;
  1361.     False:
  1362.       case (Run + UTF8Width[Buf[Run]] < TheEnd) and (Buf[Run] > #191) of
  1363.         True: UTF8IdentifierHandler;
  1364.       else
  1365.         case Range of
  1366.           drNormal: KeyList.Hash(Start);
  1367.           drAnsiDirective: DirectiveKeyList.Hash(Start);
  1368.           drBorlandDirective: DirectiveKeyList.Hash(Start);
  1369.         end;
  1370.       end;
  1371.   end;
  1372. end;
  1373.  
  1374. procedure TmwD4NLexer.InternationalIdentifierHandler;
  1375. begin
  1376.   inc(Run);
  1377.   Id := leIdentifier;
  1378.   ExId := leInternationalIdentifier;
  1379.   while (Run < TheEnd) do
  1380.     case InInternationalIdentifiers[Buf[Run]] of
  1381.       True: inc(Run);
  1382.       False: Break;
  1383.     end;
  1384.   if (Run + UTF8Width[Buf[Run]] < TheEnd) and (Buf[Run] > #191) then
  1385.     UTF8IdentifierHandler;
  1386. end;
  1387.  
  1388. procedure TmwD4NLexer.InitializeDirectives;
  1389. begin
  1390.   fApptype := atGUI;
  1391.   fRecordAlignment := 8;
  1392.   fImageBase := $00400000;
  1393.   fMinStackSize := 16384;
  1394.   fMaxStackSize := 1048576;
  1395.   fResourceReserve := IntToStr(1048576);
  1396.   fMinEnumSize := 1;
  1397.   Include(fBooleanDirectives, bdAlign);
  1398.   Include(fBooleanDirectives, bdAssertions);
  1399.   Exclude(fBooleanDirectives, bdBoolEval);
  1400.   Include(fBooleanDirectives, bdDebugInfo);
  1401.   Include(fBooleanDirectives, bdDefinitionInfo);
  1402.   Exclude(fBooleanDirectives, bdDenyPackageUnit);
  1403.   Exclude(fBooleanDirectives, bdDesignOnly);
  1404.   Include(fBooleanDirectives, bdExtendedSyntax);
  1405.   Include(fBooleanDirectives, bdImportedData);
  1406.   Include(fBooleanDirectives, bdLongStrings);
  1407.   Include(fBooleanDirectives, bdHints);
  1408.   Include(fBooleanDirectives, bdIOChecks);
  1409.   Include(fBooleanDirectives, bdImplicitBuild);
  1410.   Exclude(fBooleanDirectives, bdWriteableConst);
  1411.   Include(fBooleanDirectives, bdLocalSymbols);
  1412.   Exclude(fBooleanDirectives, bdTypeInfo);
  1413.   Exclude(fBooleanDirectives, bdObjExportAll);
  1414.   Include(fBooleanDirectives, bdOptimization);
  1415.   Include(fBooleanDirectives, bdOpenStrings);
  1416.   Exclude(fBooleanDirectives, bdOverFlowChecks);
  1417.   Exclude(fBooleanDirectives, bdRangeChecks);
  1418.   Exclude(fBooleanDirectives, bdStackFrames);
  1419.   Exclude(fBooleanDirectives, bdWeakPackageUnit);
  1420.   Include(fBooleanDirectives, bdWarnings);
  1421.   Include(fBooleanDirectives, bdSymbol_Platform);
  1422.   Include(fBooleanDirectives, bdSymbol_Library);
  1423.   Include(fBooleanDirectives, bdSymbol_Deprecated);
  1424.   Include(fBooleanDirectives, bdUnit_Deprecated);
  1425.   Include(fBooleanDirectives, bdUnit_Library);
  1426.   Include(fBooleanDirectives, bdUnit_Platform);
  1427.   Include(fBooleanDirectives, bdVarStringChecks);
  1428.   Exclude(fBooleanDirectives, bdSafeDivide);
  1429.   Exclude(fBooleanDirectives, bdTypedAddress);
  1430.   Exclude(fBooleanDirectives, bdStackChecks);
  1431.   Exclude(fBooleanDirectives, bdRunOnly);
  1432.   Exclude(fBooleanDirectives, bdRealCompatibility);
  1433. end;
  1434.  
  1435. procedure TmwD4NLexer.InitializeKeyTables;
  1436. begin
  1437.   {KeyWords}
  1438.   KeyList.Add('And', leAnd, leDelphiKeyWord);
  1439.   KeyList.Add('Array', leArray, leDelphiKeyWord);
  1440.   KeyList.Add('As', leAs, leDelphiKeyWord);
  1441.   KeyList.Add('Asm', leAsm, leDelphiKeyWord);
  1442.   KeyList.Add('Begin', leBegin, leDelphiKeyWord);
  1443.   KeyList.Add('Case', leCase, leDelphiKeyWord);
  1444.   KeyList.Add('Class', leClass, leDelphiKeyWord);
  1445.   KeyList.Add('Const', leConst, leDelphiKeyWord);
  1446.   KeyList.Add('Constructor', leConstructor, leDelphiKeyWord);
  1447.   KeyList.Add('Destructor', leDestructor, leDelphiKeyWord);
  1448.   KeyList.Add('Dispinterface', leDispinterface, leDelphiKeyWord);
  1449.   KeyList.Add('Div', leDiv, leDelphiKeyWord);
  1450.   KeyList.Add('Do', leDo, leDelphiKeyWord);
  1451.   KeyList.Add('Downto', leDownto, leDelphiKeyWord);
  1452.   KeyList.Add('Else', leElse, leDelphiKeyWord);
  1453.   KeyList.Add('End', leEnd, leDelphiKeyWord);
  1454.   KeyList.Add('Except', leExcept, leDelphiKeyWord);
  1455.   KeyList.Add('Exports', leExports, leDelphiKeyWord);
  1456.   KeyList.Add('File', leFile, leDelphiKeyWord);
  1457.   KeyList.Add('Final', leFinal, leDelphiKeyWord);
  1458.   KeyList.Add('Finalization', leFinalization, leDelphiKeyWord);
  1459.   KeyList.Add('Finally', leFinally, leDelphiKeyWord);
  1460.   KeyList.Add('For', leFor, leDelphiKeyWord);
  1461.   KeyList.Add('Function', leFunction, leDelphiKeyWord);
  1462.   KeyList.Add('Goto', leGoto, leDelphiKeyWord);
  1463.   KeyList.Add('If', leIf, leDelphiKeyWord);
  1464.   KeyList.Add('Implementation', leImplementation, leDelphiKeyWord);
  1465.   KeyList.Add('In', leIn, leDelphiKeyWord);
  1466.   KeyList.Add('Inherited', leInherited, leDelphiKeyWord);
  1467.   KeyList.Add('Initialization', leInitialization, leDelphiKeyWord);
  1468.   KeyList.Add('Inline', leInline, leDelphiKeyWord);
  1469.   KeyList.Add('Interface', leInterface, leDelphiKeyWord);
  1470.   KeyList.Add('Is', leIs, leDelphiKeyWord);
  1471.   KeyList.Add('Label', leLabel, leDelphiKeyWord);
  1472.   KeyList.Add('Library', leLibrary, leDelphiDirective);
  1473.   KeyList.Add('Mod', leMod, leDelphiKeyWord);
  1474.   KeyList.Add('Nil', leNil, leDelphiKeyWord);
  1475.   KeyList.Add('Not', leNot, leDelphiKeyWord);
  1476.   KeyList.Add('Object', leObject, leDelphiKeyWord);
  1477.   KeyList.Add('Of', leOf, leDelphiKeyWord);
  1478.   KeyList.Add('Or', leOr, leDelphiKeyWord);
  1479.   KeyList.Add('Packed', lePacked, leDelphiKeyWord);
  1480.   KeyList.Add('Procedure', leProcedure, leDelphiKeyWord);
  1481.   KeyList.Add('Program', leProgram, leDelphiKeyWord);
  1482.   KeyList.Add('Property', leProperty, leDelphiKeyWord);
  1483.   KeyList.Add('Raise', leRaise, leDelphiKeyWord);
  1484.   KeyList.Add('Record', leRecord, leDelphiKeyWord);
  1485.   KeyList.Add('Repeat', leRepeat, leDelphiKeyWord);
  1486.   KeyList.Add('Resourcestring', leResourcestring, leDelphiKeyWord);
  1487.   KeyList.Add('Sealed', leSealed, leDelphiKeyWord);
  1488.   KeyList.Add('Set', leSet, leDelphiKeyWord);
  1489.   KeyList.Add('Shl', leShl, leDelphiKeyWord);
  1490.   KeyList.Add('Shr', leShr, leDelphiKeyWord);
  1491.   KeyList.Add('String', leString, leDelphiKeyWord);
  1492.   KeyList.Add('Then', leThen, leDelphiKeyWord);
  1493.   KeyList.Add('Threadvar', leThreadvar, leDelphiKeyWord);
  1494.   KeyList.Add('To', leTo, leDelphiKeyWord);
  1495.   KeyList.Add('Try', leTry, leDelphiKeyWord);
  1496.   KeyList.Add('Type', leType, leDelphiKeyWord);
  1497.   KeyList.Add('Unit', leUnit, leDelphiKeyWord);
  1498.   KeyList.Add('Until', leUntil, leDelphiKeyWord);
  1499.   KeyList.Add('Uses', leUses, leDelphiKeyWord);
  1500.   KeyList.Add('Var', leVar, leDelphiKeyWord);
  1501.   KeyList.Add('While', leWhile, leDelphiKeyWord);
  1502.   KeyList.Add('With', leWith, leDelphiKeyWord);
  1503.   KeyList.Add('Xor', leXor, leDelphiKeyWord);
  1504.  
  1505.   {Directives}
  1506.   KeyList.Add('Absolute', leIdentifier, leAbsolute);
  1507.   KeyList.Add('Abstract', leIdentifier, leAbstract);
  1508.   KeyList.Add('Assembler', leIdentifier, leAssembler);
  1509.   KeyList.Add('At', leIdentifier, leAt);
  1510.   KeyList.Add('Automated', leIdentifier, leAutomated);
  1511.   KeyList.Add('Cdecl', leIdentifier, leCdecl);
  1512.   KeyList.Add('Contains', leIdentifier, leContains);
  1513.   KeyList.Add('Default', leIdentifier, leDefault);
  1514.   KeyList.Add('Deprecated', leIdentifier, leDeprecated);
  1515.   KeyList.Add('Dispid', leIdentifier, leDispid);
  1516.   KeyList.Add('Dynamic', leIdentifier, leDynamic);
  1517.   KeyList.Add('Experimental', leIdentifier, leExperimental);
  1518.   KeyList.Add('Export', leIdentifier, leExport);
  1519.   KeyList.Add('External', leIdentifier, leExternal);
  1520.   KeyList.Add('Far', leIdentifier, leFar);
  1521.   KeyList.Add('Forward', leIdentifier, leForward);
  1522.   KeyList.Add('Helper', leIdentifier, leHelper);
  1523.   KeyList.Add('Implements', leIdentifier, leImplements);
  1524.   KeyList.Add('Index', leIdentifier, leIndex);
  1525.   KeyList.Add('Local', leIdentifier, leLocal);
  1526.   KeyList.Add('Message', leIdentifier, leMessage);
  1527.   KeyList.Add('Name', leIdentifier, leName);
  1528.   KeyList.Add('Near', leIdentifier, leNear);
  1529.   KeyList.Add('Nodefault', leIdentifier, leNodefault);
  1530.   KeyList.Add('On', leIdentifier, leOn);
  1531.   KeyList.Add('Out', leIdentifier, leOut);
  1532.   KeyList.Add('Overload', leIdentifier, leOverload);
  1533.   KeyList.Add('Override', leIdentifier, leOverride);
  1534.   KeyList.Add('Package', leIdentifier, lePackage);
  1535.   KeyList.Add('Pascal', leIdentifier, lePascal);
  1536.   KeyList.Add('Platform', leIdentifier, lePlatform);
  1537.   KeyList.Add('Private', leIdentifier, lePrivate);
  1538.   KeyList.Add('Protected', leIdentifier, leProtected);
  1539.   KeyList.Add('Public', leIdentifier, lePublic);
  1540.   KeyList.Add('Published', leIdentifier, lePublished);
  1541.   KeyList.Add('Read', leIdentifier, leRead);
  1542.   KeyList.Add('Readonly', leIdentifier, leReadonly);
  1543.   KeyList.Add('Register', leIdentifier, leRegister);
  1544.   KeyList.Add('Reintroduce', leIdentifier, leReintroduce);
  1545.   KeyList.Add('Requires', leIdentifier, leRequires);
  1546.   KeyList.Add('Resident', leIdentifier, leResident);
  1547.   KeyList.Add('Safecall', leIdentifier, leSafecall);
  1548.   KeyList.Add('Stdcall', leIdentifier, leStdcall);
  1549.   KeyList.Add('Stored', leIdentifier, leStored);
  1550.   KeyList.Add('Strict', leIdentifier, leStrict);
  1551.   KeyList.Add('Varargs', leIdentifier, leVarargs);
  1552.   KeyList.Add('Virtual', leIdentifier, leVirtual);
  1553.   KeyList.Add('Write', leIdentifier, leWrite);
  1554.   KeyList.Add('Writeonly', leIdentifier, leWriteonly);
  1555.  
  1556.   {Additional}
  1557.   DirectiveKeyList.Add('A', leA, leIdentifier);
  1558.   DirectiveKeyList.Add('B', leB, leIdentifier);
  1559.   DirectiveKeyList.Add('C', leC, leIdentifier);
  1560.   DirectiveKeyList.Add('D', leD, leIdentifier);
  1561.   DirectiveKeyList.Add('E', leE, leIdentifier);
  1562.   DirectiveKeyList.Add('G', leG, leIdentifier);
  1563.   DirectiveKeyList.Add('H', leH, leIdentifier);
  1564.   DirectiveKeyList.Add('I', leI, leIdentifier);
  1565.   DirectiveKeyList.Add('J', leJ, leIdentifier);
  1566.   DirectiveKeyList.Add('L', leL, leIdentifier);
  1567.   DirectiveKeyList.Add('M', leM, leIdentifier);
  1568.   DirectiveKeyList.Add('O', leO, leIdentifier);
  1569.   DirectiveKeyList.Add('P', leP, leIdentifier);
  1570.   DirectiveKeyList.Add('Q', leQ, leIdentifier);
  1571.   DirectiveKeyList.Add('R', leR, leIdentifier);
  1572.   DirectiveKeyList.Add('S', leS, leIdentifier);
  1573.   DirectiveKeyList.Add('T', leT, leIdentifier);
  1574.   DirectiveKeyList.Add('U', leU, leIdentifier);
  1575.   DirectiveKeyList.Add('V', leV, leIdentifier);
  1576.   DirectiveKeyList.Add('W', leW, leIdentifier);
  1577.   DirectiveKeyList.Add('X', leX, leIdentifier);
  1578.   DirectiveKeyList.Add('Y', leY, leIdentifier);
  1579.   DirectiveKeyList.Add('Z', leZ, leIdentifier);
  1580.   DirectiveKeyList.Add('And', leAndDirective, leIdentifier);
  1581.   DirectiveKeyList.Add('Off', leOff, leIdentifier);
  1582.   DirectiveKeyList.Add('YD', leYD, leIdentifier);
  1583.   DirectiveKeyList.Add('On', leOnDirective, leIdentifier);
  1584.   DirectiveKeyList.Add('If', leIfDirective, leIdentifier);
  1585.   DirectiveKeyList.Add('IfDef', leIfDef, leIdentifier);
  1586.   DirectiveKeyList.Add('Or', leOrDirective, leIdentifier);
  1587.   DirectiveKeyList.Add('GUI', leGUI, leIdentifier);
  1588.   DirectiveKeyList.Add('EndIf', leEndIf, leIdentifier);
  1589.   DirectiveKeyList.Add('IfEnd', leIfEnd, leIdentifier);
  1590.   DirectiveKeyList.Add('Else', leElseDirective, leIdentifier);
  1591.   DirectiveKeyList.Add('Define', leDefine, leIdentifier);
  1592.   DirectiveKeyList.Add('Align', leAlign, leIdentifier);
  1593.   DirectiveKeyList.Add('IfNDef', leIfNDef, leIdentifier);
  1594.   DirectiveKeyList.Add('Link', leLink, leIdentifier);
  1595.   DirectiveKeyList.Add('Defined', leDefined, leIdentifier);
  1596.   DirectiveKeyList.Add('UnDef', leUnDef, leIdentifier);
  1597.   DirectiveKeyList.Add('Declared', leDeclared, leIdentifier);
  1598.   DirectiveKeyList.Add('ElseIf', leElseIf, leIdentifier);
  1599.   DirectiveKeyList.Add('ImageBase', leImageBase, leIdentifier);
  1600.   DirectiveKeyList.Add('IfOpt', leIfOpt, leIdentifier);
  1601.   DirectiveKeyList.Add('SoName', leSoName, leIdentifier);
  1602.   DirectiveKeyList.Add('Include', leInclude, leIdentifier);
  1603.   DirectiveKeyList.Add('Hints', leHints, leIdentifier);
  1604.   DirectiveKeyList.Add('NoDefine', leNoDefine, leIdentifier);
  1605.   DirectiveKeyList.Add('IOChecks', leIOChecks, leIdentifier);
  1606.   DirectiveKeyList.Add('DebugInfo', leDebugInfo, leIdentifier);
  1607.   DirectiveKeyList.Add('Console', leConsole, leIdentifier);
  1608.   DirectiveKeyList.Add('Booleval', leBooleval, leIdentifier);
  1609.   DirectiveKeyList.Add('HPPEmit', leHPPEmit, leIdentifier);
  1610.   DirectiveKeyList.Add('RangeChecks', leRangeChecks, leIdentifier);
  1611.   DirectiveKeyList.Add('NoInclude', leNoInclude, leIdentifier);
  1612.   DirectiveKeyList.Add('Apptype', leApptype, leIdentifier);
  1613.   DirectiveKeyList.Add('SafeDivide', leSafeDivide, leIdentifier);
  1614.   DirectiveKeyList.Add('Resource', leResource, leIdentifier);
  1615.   DirectiveKeyList.Add('Warn', leWarn, leIdentifier);
  1616.   DirectiveKeyList.Add('Warnings', leWarnings, leIdentifier);
  1617.   DirectiveKeyList.Add('TypeInfo', leTypeInfo, leIdentifier);
  1618.   DirectiveKeyList.Add('SoPrefix', leSoPrefix, leIdentifier);
  1619.   DirectiveKeyList.Add('StackFrames', leStackFrames, leIdentifier);
  1620.   DirectiveKeyList.Add('RunOnly', leRunOnly, leIdentifier);
  1621.   DirectiveKeyList.Add('SoSuffix', leSoSuffix, leIdentifier);
  1622.   DirectiveKeyList.Add('ReferenceInfo', leReferenceInfo, leIdentifier);
  1623.   DirectiveKeyList.Add('DesignOnly', leDesignOnly, leIdentifier);
  1624.   DirectiveKeyList.Add('Extension', leExtension, leIdentifier);
  1625.   DirectiveKeyList.Add('ImportedData', leImportedData, leIdentifier);
  1626.   DirectiveKeyList.Add('Description', leDescription, leIdentifier);
  1627.   DirectiveKeyList.Add('SoVersion', leSoVersion, leIdentifier);
  1628.   DirectiveKeyList.Add('Assertions', leAssertions, leIdentifier);
  1629.   DirectiveKeyList.Add('ImplicitBuild', leImplicitBuild, leIdentifier);
  1630.   DirectiveKeyList.Add('TypedAddress', leTypedAddress, leIdentifier);
  1631.   DirectiveKeyList.Add('LocalSymbols', leLocalSymbols, leIdentifier);
  1632.   DirectiveKeyList.Add('MinEnumSize', leMinEnumSize, leIdentifier);
  1633.   DirectiveKeyList.Add('WeakPackageUnit', leWeakPackageUnit, leIdentifier);
  1634.   DirectiveKeyList.Add('DefinitionInfo', leDefinitionInfo, leIdentifier);
  1635.   DirectiveKeyList.Add('MinStackSize', leMinStackSize, leIdentifier);
  1636.   DirectiveKeyList.Add('ObjExportAll', leObjExportAll, leIdentifier);
  1637.   DirectiveKeyList.Add('MaxStackSize', leMaxStackSize, leIdentifier);
  1638.   DirectiveKeyList.Add('LongStrings', leLongStrings, leIdentifier);
  1639.   DirectiveKeyList.Add('DenyPackageUnit', leDenyPackageUnit, leIdentifier);
  1640.   DirectiveKeyList.Add('ExternalSym', leExternalSym, leIdentifier);
  1641.   DirectiveKeyList.Add('OpenStrings', leOpenStrings, leIdentifier);
  1642.   DirectiveKeyList.Add('OverFlowChecks', leOverFlowChecks, leIdentifier);
  1643.   DirectiveKeyList.Add('WriteableConst', leWriteableConst, leIdentifier);
  1644.   DirectiveKeyList.Add('Optimization', leOptimization, leIdentifier);
  1645.   DirectiveKeyList.Add('VarStringChecks', leVarStringChecks, leIdentifier);
  1646.   DirectiveKeyList.Add('ExtendedSyntax', leExtendedSyntax, leIdentifier);
  1647.   DirectiveKeyList.Add('RealCompatibility', leRealCompatibility, leIdentifier);
  1648.   DirectiveKeyList.Add('ResourceReserve', leResourceReserve, leIdentifier);
  1649.   DirectiveKeyList.Add('Region', leRegion, leIdentifier);
  1650.   DirectiveKeyList.Add('EndRegion', leEndRegion, leIdentifier);
  1651.   DirectiveKeyList.Add('StackChecks', leStackChecks, leIdentifier);
  1652.   DirectiveKeyList.Add('Symbol_Platform', leSymbol_Platform, leIdentifier);
  1653.   DirectiveKeyList.Add('Symbol_Library', leSymbol_Library, leIdentifier);
  1654.   DirectiveKeyList.Add('Symbol_Deprecated', leSymbol_Deprecated, leIdentifier);
  1655.   DirectiveKeyList.Add('Unit_Deprecated', leUnit_Deprecated, leIdentifier);
  1656.   DirectiveKeyList.Add('Unit_Library', leUnit_Library, leIdentifier);
  1657.   DirectiveKeyList.Add('Unit_Platform', leUnit_Platform, leIdentifier);
  1658. end;
  1659.  
  1660. procedure TmwD4NLexer.InitTables;
  1661. var
  1662.   I: AnsiChar;
  1663.   S: AnsiString;
  1664. begin
  1665.   for I := #0 to #255 do
  1666.   begin
  1667.     case I in ['0'..'9', 'A'..'Z', 'a'..'z', '_'] of
  1668.       True:
  1669.         begin
  1670.           InIdentifiers[I] := True;
  1671.           InInternationalIdentifiers[I] := True;
  1672.         end;
  1673.       False:
  1674.         begin
  1675.           InIdentifiers[I] := False;
  1676.           case I < #192 of
  1677.             True:
  1678.               case IsCharAlphaA(I) of
  1679.                 True: InInternationalIdentifiers[I] := True;
  1680.                 False: InInternationalIdentifiers[I] := False;
  1681.               end;
  1682.             False: InInternationalIdentifiers[I] := False;
  1683.           end
  1684.         end;
  1685.     end;
  1686.     S := AnsiUpperCase(I);
  1687.     case S <> '' of
  1688.       True: UpperMap[Ord(I)] := Ord(S[1]);
  1689.       False: UpperMap[Ord(I)] := Ord(I);
  1690.     end;
  1691.   end;
  1692. end;
  1693.  
  1694. procedure TmwD4NLexer.LessHandler;
  1695. begin
  1696.   inc(Run);
  1697.   Id := leLess;
  1698.   if Run < TheEnd then
  1699.     case Buf[Run] of
  1700.       '=':
  1701.         begin
  1702.           Id := leLessOrEqual;
  1703.           inc(Run);
  1704.         end;
  1705.       '>':
  1706.         begin
  1707.           Id := leNotEqual;
  1708.           inc(Run);
  1709.         end;
  1710.     end;
  1711. end;
  1712.  
  1713. procedure TmwD4NLexer.LFHandler;
  1714. begin
  1715.   inc(Run);
  1716.   Id := leLF;
  1717.   fLinePosition := Start;
  1718.   inc(fLineNumber);
  1719. end;
  1720.  
  1721. procedure TmwD4NLexer.MinusHandler;
  1722. begin
  1723.   inc(Run);
  1724.   Id := leMinus;
  1725. end;
  1726.  
  1727. procedure TmwD4NLexer.Next;
  1728. begin
  1729.   Start := Run;
  1730.   ExId := leUnknown;
  1731.   case Run < TheEnd of
  1732.     True:
  1733.       case Range of
  1734.         drNormal,
  1735.           drAnsiDirective,
  1736.           drBorlandDirective:
  1737.           case Buf[Run] of
  1738.             #0..#9: SpaceHandler;
  1739.             #10: LFHandler;
  1740.             #11, #12: SpaceHandler;
  1741.             #13: CRHandler;
  1742.             #14..#32: SpaceHandler;
  1743.             '!': ExclamHandler;
  1744.             '"': DoubleQuoteHandler;
  1745.             '#': SharpHandler;
  1746.             '$': DollarHandler;
  1747.             '%': PercentHandler;
  1748.             '&': AmpersandHandler;
  1749.             '''': ApostropheHandler;
  1750.             '(': RoundOpenHandler;
  1751.             ')': RoundCloseHandler;
  1752.             '*': AsteriskHandler;
  1753.             '+': PlusHandler;
  1754.             ',': CommaHandler;
  1755.             '-': MinusHandler;
  1756.             '.': PeriodHandler;
  1757.             '/': SlashHandler;
  1758.             '0'..'9': NumberHandler;
  1759.             ':': ColonHandler;
  1760.             ';': SemicolonHandler;
  1761.             '<': LessHandler;
  1762.             '=': EqualHandler;
  1763.             '>': GreaterHandler;
  1764.             '?': QuestionHandler;
  1765.             '@': AtHandler;
  1766.             'A'..'Z': IdentifierHandler;
  1767.             '[': SquareOpenHandler;
  1768.             '\': BackslashHandler;
  1769.             ']': SquareCloseHandler;
  1770.             '^': AsciiCircumHandler;
  1771.             '_': IdentifierHandler;
  1772.             '`': QuoteLeftHandler;
  1773.             'a'..'z': IdentifierHandler;
  1774.             '{': CurlyOpenHandler;
  1775.             '|': BarHandler;
  1776.             '}': CurlyCloseHandler;
  1777.             '~': AsciiTildeHandler;
  1778.           else
  1779.             case InInternationalIdentifiers[Buf[Run]] of
  1780.               True: InternationalIdentifierHandler;
  1781.               False:
  1782.                 case (Buf[Run] > #191) and (Run + UTF8Width[Buf[Run]] <= TheEnd) of
  1783.                   True: InternationalIdentifierHandler;
  1784.                   False: UnknownHandler;
  1785.                 end;
  1786.             end;
  1787.           end;
  1788.         drAssemblerReference: NextAssemblerReference;
  1789.         drAnsiComment: NextAnsiComment;
  1790.         drBorlandComment: NextBorlandComment;
  1791.       end;
  1792.     False: Id := leAtEnd;
  1793.   end
  1794. end;
  1795.  
  1796. procedure TmwD4NLexer.NextNoSpace;
  1797. begin
  1798.   repeat
  1799.     Next;
  1800.   until (Id <> leSpace) and (Id <> leLineEnd) and (Id <> leLF);
  1801. end;
  1802.  
  1803. procedure TmwD4NLexer.NextToken;
  1804. begin
  1805.   Next;
  1806. end;
  1807.  
  1808. procedure TmwD4NLexer.NextAnsiComment;
  1809. begin
  1810.   Start := Run;
  1811.   ExId := leUnknown;
  1812.   case Run < TheEnd of
  1813.     True:
  1814.       case Buf[Run] of
  1815.         #10: LFHandler;
  1816.         #13: CRHandler;
  1817.       else
  1818.         AnsiCommentHandler;
  1819.       end;
  1820.     False: Id := leAtEnd;
  1821.   end
  1822. end;
  1823.  
  1824. procedure TmwD4NLexer.NextAssemblerReference;
  1825. begin
  1826.   Start := Run;
  1827.   ExId := leUnknown;
  1828.   case Run < TheEnd of
  1829.     True:
  1830.       case Buf[Run] of
  1831.         #10: LFHandler;
  1832.         #13: CRHandler;
  1833.       else
  1834.         AssemblerReferenceHandler;
  1835.       end;
  1836.     False: Id := leAtEnd;
  1837.   end
  1838. end;
  1839.  
  1840. procedure TmwD4NLexer.NextBorlandComment;
  1841. begin
  1842.   Start := Run;
  1843.   ExId := leUnknown;
  1844.   case Run < TheEnd of
  1845.     True:
  1846.       case Buf[Run] of
  1847.         #10: LFHandler;
  1848.         #13: CRHandler;
  1849.       else
  1850.         BorlandCommentHandler;
  1851.       end;
  1852.     False: Id := leAtEnd;
  1853.   end
  1854. end;
  1855.  
  1856. procedure TmwD4NLexer.NumberHandler;
  1857. begin
  1858.   Id := leNumber;
  1859.   inc(Run);
  1860.   while (Run < TheEnd) and ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  1861.     case Run < TheEnd of
  1862.       True: inc(Run);
  1863.       False: Break;
  1864.     end;
  1865.   if Run < TheEnd then
  1866.     case Buf[Run] of
  1867.       '.':
  1868.         begin
  1869.           inc(Run);
  1870.           Id := leFloat;
  1871.           if Run < TheEnd then
  1872.             case Buf[Run] of
  1873.               'E', 'e':
  1874.                 if Run + 1 < TheEnd then
  1875.                   case Buf[Run + 1] of
  1876.                     '+', '-':
  1877.                       if Run + 2 < TheEnd then
  1878.                         if ((Buf[Run + 2] >= '0') and (Buf[Run + 2] <= '9')) then
  1879.                         begin
  1880.                           inc(Run, 2);
  1881.                           while (Run < TheEnd) and
  1882.                             ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  1883.                             inc(Run);
  1884.                         end;
  1885.                     '0'..'9':
  1886.                       if Run + 1 < TheEnd then
  1887.                       begin
  1888.                         inc(Run, 2);
  1889.                         while (Run < TheEnd) and
  1890.                           ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  1891.                           inc(Run);
  1892.                       end;
  1893.                   end;
  1894.               '0'..'9':
  1895.                 begin
  1896.                   while (Run < TheEnd) and
  1897.                     ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  1898.                     inc(Run);
  1899.                   if Run < TheEnd then
  1900.                     case Buf[Run] of
  1901.                       'E', 'e':
  1902.                         if Run + 1 < TheEnd then
  1903.                           case Buf[Run + 1] of
  1904.                             '+', '-':
  1905.                               if Run + 1 < TheEnd then
  1906.                                 if ((Buf[Run + 2] >= '0') and (Buf[Run + 2] <= '9')) then
  1907.                                 begin
  1908.                                   inc(Run, 2);
  1909.                                   while (Run < TheEnd) and
  1910.                                     ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  1911.                                     inc(Run);
  1912.                                 end;
  1913.                             '0'..'9':
  1914.                               if Run + 1 < TheEnd then
  1915.                               begin
  1916.                                 inc(Run, 2);
  1917.                                 while (Run < TheEnd) and
  1918.                                   ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  1919.                                   inc(Run);
  1920.                               end;
  1921.                           end;
  1922.                     end;
  1923.                 end;
  1924.             end;
  1925.         end;
  1926.       'E', 'e':
  1927.         if Run < TheEnd then
  1928.           case Buf[Run + 1] of
  1929.             '+', '-':
  1930.               if Run + 2 < TheEnd then
  1931.                 if ((Buf[Run + 2] >= '0') and (Buf[Run + 2] <= '9')) then
  1932.                 begin
  1933.                   inc(Run, 3);
  1934.                   Id := leFloat;
  1935.                   while (Run < TheEnd) and
  1936.                     ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  1937.                     inc(Run);
  1938.                 end;
  1939.             '0'..'9':
  1940.               if Run + 1 < TheEnd then
  1941.               begin
  1942.                 inc(Run, 2);
  1943.                 Id := leFloat;
  1944.                 while (Run < TheEnd) and
  1945.                   ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  1946.                   inc(Run);
  1947.               end;
  1948.           end;
  1949.     end;
  1950. end;
  1951.  
  1952. procedure TmwD4NLexer.PercentHandler;
  1953. begin
  1954.   inc(Run);
  1955.   Id := lePercent;
  1956. end;
  1957.  
  1958. procedure TmwD4NLexer.PeriodHandler;
  1959. begin
  1960.   inc(Run);
  1961.   Id := lePeriod;
  1962.   if Run < TheEnd then
  1963.     case Buf[Run] of
  1964.       '.':
  1965.         begin
  1966.           inc(Run);
  1967.           Id := leDotDot;
  1968.         end;
  1969.       ')':
  1970.         begin
  1971.           inc(Run);
  1972.           Id := leSquareClose;
  1973.         end;
  1974.     end;
  1975. end;
  1976.  
  1977. procedure TmwD4NLexer.PlusHandler;
  1978. begin
  1979.   inc(Run);
  1980.   Id := lePlus;
  1981. end;
  1982.  
  1983. procedure TmwD4NLexer.QuestionHandler;
  1984. begin
  1985.   inc(Run);
  1986.   Id := leQuestion;
  1987. end;
  1988.  
  1989. procedure TmwD4NLexer.QuoteLeftHandler;
  1990. begin
  1991.   inc(Run);
  1992.   Id := leQuoteLeft;
  1993. end;
  1994.  
  1995. function TmwD4NLexer.RetrieveIncludeFileName: AnsiString;
  1996. begin
  1997.   if Buf[Run] = '.' then
  1998.     inc(Run);
  1999.   while Buf[Run] in ['A'..'Z', 'a'..'z'] do
  2000.     inc(Run);
  2001.   Result := Token;
  2002. end;
  2003.  
  2004. function TmwD4NLexer.RetrieveResourceFileName: AnsiString;
  2005. begin
  2006.   Result := '';
  2007.   case Buf[Run] of
  2008.     '''':
  2009.       begin
  2010.         SetLength(Result, Run - Start - 2);
  2011. {$IFDEF CLR}
  2012.         System.array.Copy(Buf, Start + 1, Result, 0, Run - Start - 2);
  2013. {$ELSE}
  2014.         System.Move(Buf[Start + 1], Result[1], Run - Start - 2);
  2015. {$ENDIF}
  2016.       end;
  2017.     '*':
  2018.       begin
  2019.         inc(Run);
  2020.         Start := Run;
  2021.         if Buf[Run] = '.' then
  2022.           inc(Run);
  2023.         while Buf[Run] in ['A'..'Z', 'a'..'z'] do
  2024.           inc(Run);
  2025.         Result := FileName + Token;
  2026.       end;
  2027.   else
  2028.     if Id = leIdentifier then
  2029.     begin
  2030.       if Buf[Run] = '.' then
  2031.         inc(Run);
  2032.       while Buf[Run] in ['A'..'Z', 'a'..'z'] do
  2033.         inc(Run);
  2034.       Result := Token;
  2035.     end;
  2036.   end;
  2037. end;
  2038.  
  2039. procedure TmwD4NLexer.RoundCloseHandler;
  2040. begin
  2041.   inc(Run);
  2042.   Id := leRoundClose;
  2043. end;
  2044.  
  2045. procedure TmwD4NLexer.RoundOpenHandler;
  2046. begin
  2047.   inc(Run);
  2048.   Id := leRoundOpen;
  2049.   if Range = drNormal then
  2050.     if Run < TheEnd then
  2051.       case Buf[Run] of
  2052.         '.':
  2053.           begin
  2054.             inc(Run);
  2055.             Id := leSquareOpen;
  2056.           end;
  2057.         '*':
  2058.           begin
  2059.             inc(Run);
  2060.             Id := leAnsiComment;
  2061.             if Run < TheEnd then
  2062.               case Buf[Run] = '$' of
  2063.                 True:
  2064.                   begin
  2065.                     inc(Run);
  2066.                     Range := drAnsiDirective;
  2067.                     Id := leBeginOfAnsiDirective;
  2068.                   end;
  2069.                 False:
  2070.                   begin
  2071.                     Range := drAnsiComment;
  2072.                     AnsiCommentHandler;
  2073.                   end;
  2074.               end;
  2075.           end;
  2076.       end;
  2077. end;
  2078.  
  2079. procedure TmwD4NLexer.SemicolonHandler;
  2080. begin
  2081.   inc(Run);
  2082.   Id := leSemiColon;
  2083. end;
  2084.  
  2085. {$IFDEF CLR}
  2086.  
  2087. procedure TmwD4NLexer.SetBuf(const aBuf: array of AnsiChar);
  2088. {$ELSE}
  2089.  
  2090. procedure TmwD4NLexer.SetBuf(const aBuf: PChar; Len: Integer);
  2091. {$ENDIF}
  2092. begin
  2093.   Buf := aBuf;
  2094.   Run := 0;
  2095. {$IFDEF CLR}
  2096.   TheEnd := Length(aBuf);
  2097. {$ELSE}
  2098.   TheEnd := Len;
  2099. {$ENDIF}
  2100.   Id := leUnknown;
  2101.   fLinePosition := 0;
  2102.   fLineNumber := 0;
  2103.   NextToken;
  2104. end;
  2105.  
  2106. procedure TmwD4NLexer.SetDefaultDefines(Value: TStringList);
  2107. var
  2108.   I: Integer;
  2109. begin
  2110.   if Value = nil then Exit;
  2111.   fDefaultDefines.Assign(Value);
  2112.   for I := 0 to fDefaultDefines.Count - 1 do
  2113.     fDefinedList.Add(fDefaultDefines[I]);
  2114. end;
  2115.  
  2116. procedure TmwD4NLexer.SetDescription(Value: AnsiString);
  2117. begin
  2118.   fDescription := Value;
  2119. end;
  2120.  
  2121. procedure TmwD4NLexer.SetExtension(Value: AnsiString);
  2122. begin
  2123.   fExtension := Value;
  2124. end;
  2125.  
  2126. procedure TmwD4NLexer.SetExternalSym(Value: AnsiString);
  2127. begin
  2128.   fExternalSym := Value;
  2129. end;
  2130.  
  2131. procedure TmwD4NLexer.SetHppEmit(Value: AnsiString);
  2132. begin
  2133.   fHppEmit := Value;
  2134. end;
  2135.  
  2136. procedure TmwD4NLexer.SetImageBase(Value: Integer);
  2137. begin
  2138.   fImageBase := Value;
  2139. end;
  2140.  
  2141. procedure TmwD4NLexer.SetResourceReserve(Value: AnsiString);
  2142. begin
  2143.   fResourceReserve := Value;
  2144. end;
  2145.  
  2146. procedure TmwD4NLexer.SetMaxStackSize(Value: Integer);
  2147. begin
  2148.   fMaxStackSize := Value;
  2149. end;
  2150.  
  2151. procedure TmwD4NLexer.SetMinStackSize(Value: Integer);
  2152. begin
  2153.   fMinStackSize := Value;
  2154. end;
  2155.  
  2156. procedure TmwD4NLexer.SetMinEnumSize(Value: Integer);
  2157. begin
  2158.   if (Value = 1) or (Value = 2) or (Value = 4) then
  2159.     fMinEnumSize := Value;
  2160. end;
  2161.  
  2162. procedure TmwD4NLexer.SetNoDefine(Value: AnsiString);
  2163. begin
  2164.   fNoDefine := Value;
  2165. end;
  2166.  
  2167. procedure TmwD4NLexer.SetNoInclude(Value: AnsiString);
  2168. begin
  2169.   fNoInclude := Value;
  2170. end;
  2171.  
  2172. procedure TmwD4NLexer.SetResFileName(Value: AnsiString);
  2173. begin
  2174.   fResFileName := Value;
  2175. end;
  2176.  
  2177. procedure TmwD4NLexer.SetRcFileName(Value: AnsiString);
  2178. begin
  2179.   fRcFileName := Value;
  2180. end;
  2181.  
  2182. procedure TmwD4NLexer.SetRegionString(Value: AnsiString);
  2183. begin
  2184.   fRegionString := Value;
  2185. end;
  2186.  
  2187. procedure TmwD4NLexer.SharpHandler;
  2188. begin
  2189.   inc(Run);
  2190.   Id := leSharp;
  2191.   if Run < TheEnd then
  2192.     case Buf[Run] of
  2193.       '$':
  2194.         begin
  2195.           inc(Run);
  2196.           Id := leCharHexConstant;
  2197.           while (Run < TheEnd) and
  2198.             ((Buf[Run] >= '0') and (Buf[Run] <= '9')) or
  2199.             ((Buf[Run] >= 'a') and (Buf[Run] <= 'f')) or
  2200.             ((Buf[Run] >= 'A') and (Buf[Run] <= 'F')) do
  2201.             inc(Run);
  2202.         end;
  2203.       '0'..'9':
  2204.         begin
  2205.           inc(Run);
  2206.           Id := leCharConstant;
  2207.           while (Run < TheEnd) and
  2208.             ((Buf[Run] >= '0') and (Buf[Run] <= '9')) do
  2209.             inc(Run);
  2210.         end;
  2211.     end;
  2212. end;
  2213.  
  2214. procedure TmwD4NLexer.SlashHandler;
  2215. begin
  2216.   inc(Run);
  2217.   Id := leSlash;
  2218.   if Range = drNormal then
  2219.     case Run < TheEnd of
  2220.       True:
  2221.         if Buf[Run] = '/' then
  2222.         begin
  2223.           inc(Run);
  2224.           Id := leSlashComment;
  2225.           while Run < TheEnd do
  2226.             case Buf[Run] of
  2227.               #10: Break;
  2228.               #13: case (Run < TheEnd) and (Buf[Run + 1] = #10) of
  2229.                   True: Break;
  2230.                   False: inc(Run);
  2231.                 end;
  2232.             else
  2233.               inc(Run);
  2234.             end;
  2235.         end;
  2236.     end;
  2237. end;
  2238.  
  2239. procedure TmwD4NLexer.SpaceHandler;
  2240. begin
  2241.   inc(Run);
  2242.   Id := leSpace;
  2243.   while (Run < TheEnd) and
  2244.     (((Buf[Run] >= #0) and (Buf[Run] < #10)) or
  2245.     (Buf[Run] = #11) or
  2246.     (Buf[Run] = #12) or
  2247.     ((Buf[Run] = #13) and (Run + 1 < TheEnd) and (Buf[Run + 1] = #10)) or
  2248.     ((Buf[Run] > #13) and (Buf[Run] <= #32)))
  2249.     do inc(Run);
  2250. end;
  2251.  
  2252. procedure TmwD4NLexer.SquareCloseHandler;
  2253. begin
  2254.   inc(Run);
  2255.   Id := leSquareClose;
  2256. end;
  2257.  
  2258. procedure TmwD4NLexer.SquareOpenHandler;
  2259. begin
  2260.   inc(Run);
  2261.   Id := leSquareOpen;
  2262. end;
  2263.  
  2264. procedure TmwD4NLexer.UnknownHandler;
  2265. begin
  2266.   Id := leUnknown;
  2267.   case Run + UTF8Width[Buf[Run]] < TheEnd of
  2268.     True: inc(Run, UTF8Width[Buf[Run]]);
  2269.     False: inc(Run);
  2270.   end;
  2271. end;
  2272.  
  2273. procedure TmwD4NLexer.UTF8IdentifierHandler;
  2274. begin
  2275.   inc(Run, UTF8Width[Buf[Run]]);
  2276.   Id := leIdentifier;
  2277.   ExId := leUTF8Identifier;
  2278.   while (Run < TheEnd) do
  2279.     case InInternationalIdentifiers[Buf[Run]] of
  2280.       True: inc(Run);
  2281.       False:
  2282.         case (Buf[Run] > #191) and (Run + UTF8Width[Buf[Run]] <= TheEnd) of
  2283.           True: inc(Run, UTF8Width[Buf[Run]]);
  2284.           False: Break;
  2285.         end;
  2286.     end;
  2287. end;
  2288.  
  2289. end.
  2290.  
  2291.